<?php
/**
 *
 * @createTime: 2016-07-28 18:05
 * @description: 微信支付相关接口的数据基类
 */

namespace Payment\Common\Weixin\Data;

use Payment\Common\BaseData;
use Payment\Common\PayException;

/**
 * Class BaseData
 *
 * @property string $appId   微信分配的公众账号ID
 * @property string $mchId  微信支付分配的商户号
 * @property string $nonceStr  随机字符串，不长于32位
 * @property string $notifyUrl  异步通知的url
 * @property string $feeType  符合ISO 4217标准的三位字母代码 默认位人民币
 * @property string $timeStart  交易开始时间 格式为yyyyMMddHHmmss
 * @property string $md5Key  用于加密的md5Key
 * @property string $appCertPem 从apiclient_cert.p12中导出证书部分的文件，为pem格式，
 * @property string $appKeyPem 从apiclient_key.pem中导出密钥部分的文件，为pem格式
 * @property string $publicKeyPem 从获取RSA加密公钥API中得到的RSA公钥并进行将PKCS#1转为PKCS#8的pem格式文件
 * @property string $tradeType   支付类型
 * @property string $terminal_id 终端设备号(门店号或收银设备ID)，默认请传"WEB"
 * @property string $sub_appid
 * @property string $sub_mch_id 终端设备号(门店号或收银设备ID)，默认请传"WEB"
 * @property string $goods_tag 订单优惠标记
 *
 *
 * @package Payment\Common\Weixin\Data
 */
abstract class WxBaseData extends BaseData
{

    /**
     * 签名算法实现  便于后期扩展微信不同的加密方式
     * @param string $signStr
     * @return string
     */
    protected function makeSign($signStr)
    {
        switch ($this->signType) {
            case 'MD5':
                $signStr .= '&key=' . $this->md5Key;
                $sign = md5($signStr);
                break;
            case 'HMAC-SHA256':
                $sign = base64_encode(hash_hmac('sha256', $signStr, $this->md5Key));
                break;
            default:
                $sign = '';
        }

        return strtoupper($sign);
    }

    /**
     * RSA加密
     * @param string $string 需加密字符串
     * @return string 返回加密后字符串
     * @throws PayException
     * @createTime 2019/10/10 14:00
     */
    protected function encryptByRSA(string $string)
    {
        $publicKeyPem = $this->publicKeyPem;
        if (empty($publicKeyPem) || true !== file_exists($publicKeyPem)) throw new PayException('RSA加密公钥有误');
        $encryptedBlock = '';
        if (true !== openssl_public_encrypt($string, $encryptedBlock, file_get_contents($this->publicKeyPem), OPENSSL_PKCS1_OAEP_PADDING)) throw new PayException('RSA加密失败');
        return base64_encode($encryptedBlock);
    }

}
